<template>
  <div id="container" style="width: 100%; height: 100%"></div>
</template>

<script>
// 仅导入必要模块，移除未使用依赖
import { Graph } from '@antv/x6';
import { Keyboard } from '@antv/x6-plugin-keyboard';
import { Selection } from '@antv/x6-plugin-selection';
import Hierarchy from '@antv/hierarchy';

export default {
  name: 'MindMap',
  data() {
    return {
      graph: null, // 存储graph实例
      mindMapData: {
        // 思维导图数据（改为响应式）
        id: '1',
        type: 'topic',
        label: '中心主题',
        width: 160,
        height: 50,
        children: [
          {
            id: '1-1',
            type: 'topic-branch',
            label: '分支主题1',
            width: 100,
            height: 40,
            children: [
              {
                id: '1-1-1',
                type: 'topic-child',
                label: '子主题1',
                width: 60,
                height: 30,
              },
              {
                id: '1-1-2',
                type: 'topic-child',
                label: '子主题2',
                width: 60,
                height: 30,
              },
            ],
          },
          {
            id: '1-2',
            type: 'topic-branch',
            label: '分支主题2',
            width: 100,
            height: 40,
          },
        ],
      },
    };
  },
  mounted() {
    this.initGraph();
    this.registerShapes(); // 注册图形（无需传递graph参数）
    this.renderMindMap(); // 渲染思维导图
    this.bindEvents(); // 绑定交互事件
  },
  methods: {
    // 初始化图形配置
    initGraph() {
      this.graph = new Graph({
        container: document.getElementById('container'),
        connecting: { connectionPoint: 'anchor' },
        // 添加网格背景（可选增强）
        grid: { size: 10, visible: true, type: 'dot', color: '#f5f5f5' },
        // 启用平移缩放
        mousewheel: { enabled: true, zoomAtMousePosition: true },
        panning: { enabled: true, eventTypes: ['leftMouseDown', 'mouseWheel'] },
      });

      // 注册插件
      this.graph.use(new Selection({ enabled: true }));
      this.graph.use(new Keyboard({ enabled: true }));
    },

    // 注册自定义节点和边
    registerShapes() {
      // 中心/分支主题节点
      Graph.registerNode(
        'topic',
        {
          inherit: 'rect',
          markup: [
            { tagName: 'rect', selector: 'body' },
            { tagName: 'image', selector: 'img' },
            { tagName: 'text', selector: 'label' },
          ],
          attrs: {
            body: {
              rx: 6,
              ry: 6,
              stroke: '#5F95FF',
              fill: '#EFF4FF',
              strokeWidth: 1,
            },
            img: {
              ref: 'body',
              refX: '100%',
              refY: '50%',
              refY2: -8,
              width: 16,
              height: 16,
              class: 'topic-image',
              'xlink:href':
                'https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*SYCuQ6HHs5cAAAAAAAAAAAAAARQnAQ',
              event: 'add:topic',
            },
            label: {
              fontSize: 14,
              fill: '#262626',
              refX: '50%',
              refY: '50%',
              textAnchor: 'middle',
              textVerticalAnchor: 'middle',
            },
          },
        },
        true
      );

      // 子主题节点
      Graph.registerNode(
        'topic-child',
        {
          inherit: 'rect',
          markup: [
            { tagName: 'rect', selector: 'body' },
            { tagName: 'text', selector: 'label' },
            { tagName: 'path', selector: 'line' },
          ],
          attrs: {
            body: { fill: '#fff', strokeWidth: 0, stroke: '#5F95FF' },
            label: {
              fontSize: 14,
              fill: '#262626',
              textVerticalAnchor: 'bottom',
              refX: 0,
              refY: 15,
            },
            line: { stroke: '#5F95FF', strokeWidth: 2, d: 'M 0 15 L 60 15' },
          },
        },
        true
      );

      // 思维导图连接器
      Graph.registerConnector(
        'mindmap',
        (source, target) => {
          const midX = source.x + 10;
          const path = `M ${source.x} ${source.y} L ${midX} ${source.y} Q ${(target.x + midX) / 2} ${target.y} ${target.x} ${target.y}`;
          return path;
        },
        true
      );

      // 思维导图边
      Graph.registerEdge(
        'mindmap-edge',
        {
          inherit: 'edge',
          connector: { name: 'mindmap' },
          attrs: {
            line: { targetMarker: '', stroke: '#A2B1C3', strokeWidth: 2 },
          },
          zIndex: 0,
        },
        true
      );
    },

    // 渲染思维导图（基于响应式数据）
    renderMindMap() {
      const result = Hierarchy.mindmap(this.mindMapData, {
        direction: 'V',
        getHeight: d => d.height,
        getWidth: d => d.width,
        getHGap: () => 40,
        getVGap: () => 20,
        getSide: () => 'bottom',
      });

      const cells = [];
      const traverse = item => {
        if (!item) return;
        const { data, children } = item;

        // 添加节点
        cells.push(
          this.graph.createNode({
            id: data.id,
            shape: data.type === 'topic-child' ? 'topic-child' : 'topic',
            x: item.x - data.width / 2, // 居中调整
            y: item.y - data.height / 2,
            width: data.width,
            height: data.height,
            label: data.label,
            type: data.type,
          })
        );

        // 添加边（子节点连接）
        children?.forEach(child => {
          cells.push(
            this.graph.createEdge({
              shape: 'mindmap-edge',
              source: { cell: data.id, anchor: { name: 'bottom' } },
              target: { cell: child.data.id, anchor: { name: 'top' } },
            })
          );
          traverse(child); // 递归处理子节点
        });
      };

      traverse(result);
      this.graph.resetCells(cells);
      this.graph.centerContent(); // 居中显示
    },

    // 绑定交互事件
    bindEvents() {
      const { graph } = this;

      // 点击添加子节点（图片点击事件）
      graph.on('add:topic', ({ e, node }) => {
        e.stopPropagation();
        this.addChildNode(node.id); // 调用添加节点方法
      });

      // Tab键添加子节点（选中节点时）
      graph.bindKey('tab', () => {
        const selected = graph.getSelectedCells().find(c => c.isNode());
        if (selected) this.addChildNode(selected.id);
      });

      // 删除选中节点（Backspace/Delete键）
      graph.bindKey(['backspace', 'delete'], () => {
        const selected = graph.getSelectedCells().find(c => c.isNode());
        if (selected) this.removeNode(selected.id);
      });
    },

    // 添加子节点（修改响应式数据）
    addChildNode(parentId) {
      // 查找父节点并添加子节点
      const addChild = data => {
        if (data.id === parentId) {
          // 生成唯一ID（示例：parentId-时间戳后4位）
          const childId = `${parentId}-${Date.now().toString().slice(-4)}`;
          data.children = data.children || [];
          data.children.push({
            id: childId,
            type: 'topic-child',
            label: `新子主题`,
            width: 60,
            height: 30,
          });
          return true;
        }
        if (data.children) {
          for (const child of data.children) {
            if (addChild(child)) return true;
          }
        }
        return false;
      };

      addChild(this.mindMapData); // 递归查找并添加
      this.renderMindMap(); // 重新渲染
      return true;
    },

    // 删除节点（修改响应式数据）
    removeNode(nodeId) {
      // 递归查找并删除节点
      const remove = data => {
        if (data.children) {
          const index = data.children.findIndex(c => c.id === nodeId);
          if (index > -1) {
            data.children.splice(index, 1);
            return true;
          }
          for (const child of data.children) {
            if (remove(child)) return true;
          }
        }
        return false;
      };

      remove(this.mindMapData); // 执行删除
      this.renderMindMap(); // 重新渲染
      return true;
    },
  },
};
</script>

<style scoped>
/* 容器样式确保显示 */
#container {
  width: 100%;
  height: 80vh;
}
/* 节点图片样式 */
.topic-image {
  visibility: hidden;
  cursor: pointer;
}
.x6-node:hover .topic-image {
  visibility: visible;
}
/* 选中节点样式 */
.x6-node-selected rect {
  stroke-width: 2px;
  stroke: #5f95ff;
}
.x6-node-selected .topic-image {
  visibility: visible;
}
</style>
